/**
 * stream.c
 *
 *  Created on: 2019-09-05
 *      Author: chenshisheng
 */

#include "stream/stream.h"

void Stream_Init(Stream_t *stream, Stream_Put_t put, Stream_Get_t get, Stream_Flush_t flush)
{
//    osMutexDef(stream);

    stream->put = put;
    stream->get = get;
    stream->flush = flush;
//    stream->mutexId = osMutexCreate(osMutex(stream));
}

void Stream_InitWithoutMutex(Stream_t *stream, Stream_Put_t put, Stream_Get_t get, Stream_Flush_t flush)
{
    stream->put = put;
    stream->get = get;
    stream->flush = flush;
//    stream->mutexId = NULL;
}

int Stream_Write(void *instance, const void *data, unsigned int size)
{
    int ret;
    unsigned int i;
    Stream_t *stream = instance;
    const uint8_t *pwd = data;

    Stream_MutexWait(instance);
    for(i = 0; i < size; i++)
    {
        ret = Stream_Put(stream, pwd[i]);
        if(ret != 1)
        {
            break;
        }
    }

    Stream_MutexRelease(instance);
    return (int)i;
}

int Stream_Read(void *instance, void *data, unsigned int size)
{
    int ret;
    unsigned int i;
    Stream_t *stream = instance;
    uint8_t *prd = data;

    Stream_MutexWait(instance);
    for(i = 0; i < size; i++)
    {
        ret = Stream_Get(stream, prd++);
        if(ret != 1)
        {
            break;
        }
    }

    Stream_MutexRelease(instance);
    return (int)i;
}

int Stream_ReadUntil(void *instance, char buf[], unsigned int maxSize, char till)
{
    unsigned int i;
    char c;
    int ret = -1;
    bool haveLine = FALSE;
    Stream_t *stream = instance;

    for(i = 0; i < (maxSize - 1); i++)
    {
        if(Stream_Get(stream, (unsigned char *) & c) != 1)
        {
            break;
        }

        if((c == '\b') && (i != 0))
        {
            i -= 1;
            continue;
        }

        if(c == till)
        {
            ret = 0;
            haveLine = TRUE;
            break;
        }

        buf[i] = c;
    }

    buf[i] = '\0';

    // 清除多余的字符
    if((! haveLine) && (i == (maxSize - 1)))
    {
        while(1)
        {
            if(Stream_Get(stream, (unsigned char *) & c) != 1)
            {
                break;
            }

            if(c == till)
            {
                break;
            }
        }
    }

    return ret;
}

void Stream_Flush(void *instance)
{
    Stream_t *stream = instance;

    Stream_MutexWait(instance);
    stream->flush(instance);
    Stream_MutexRelease(instance);
}
